import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:novel_reader/model/book.dart';
import 'package:novel_reader/model/chapter.dart';

class HiveStorage {
  static const String _booksBoxName = 'booksBox';
  static const String _chaptersBoxName = 'chaptersBox';

  static Box<Book>? _booksBox;
  static Box<Chapter>? _chaptersBox;

  static Future<void> init() async {
    await Hive.initFlutter();
    Hive.registerAdapter(ChapterAdapter());
    Hive.registerAdapter(BookAdapter());
    _booksBox = await Hive.openBox<Book>(_booksBoxName);
    _chaptersBox = await Hive.openBox<Chapter>(_chaptersBoxName);
  }

  static bool isReady() {
    return _booksBox != null && _chaptersBox != null;
  }

  static List<Book> getAllBooks() {
    _checkInitialization();
    List<Book> list = _booksBox!.values.toList();
    list.sort((a, b) => a.initTime!.compareTo(b.initTime as num));
    return list;
  }

  static Book? getBookByCode(String code) {
    _checkInitialization();
    return _booksBox!.get(code);
  }

  static Future<void> saveBook(Book book) async {
    _checkInitialization();
    await _booksBox!.put(book.code, book);
  }

  static Future<void> saveBooks(List<Book> books) async {
    _checkInitialization();
    final LinkedHashMap<String, Book> bookMap = LinkedHashMap();
    for (var book in books) {
      bookMap[book.code] = book;
    }
    await _booksBox!.putAll(bookMap);
  }

  static Future<void> deleteBook(String code) async {
    _checkInitialization();
    await _booksBox!.delete(code);
    await deleteChaptersByBookCode(code);
  }

  static List<Chapter> getChaptersByBookCode(String bookCode) {
    _checkInitialization();
    final list = _chaptersBox!.values
        .where((chapter) => chapter.bookCode == bookCode)
        .toList();
    list.sort((a, b) => a.order!.compareTo(b.order as num));
    return list;
  }

  static Future<void> saveChapter(Chapter chapter) async {
    _checkInitialization();
    final String key = '${chapter.bookCode}_${chapter.chapterId}';
    await _chaptersBox!.put(key, chapter);
  }

  static Future<void> _saveChapters(List<Chapter> chapters) async {
    _checkInitialization();
    final LinkedHashMap<String, Chapter> chapterMap = LinkedHashMap();
    for (var chapter in chapters) {
      final String key = '${chapter.bookCode}_${chapter.chapterId}';
      chapterMap[key] = chapter;
    }
    await _chaptersBox!.putAll(chapterMap);
  }

  static Future<void> deleteChaptersByBookCode(String bookCode) async {
    _checkInitialization();
    final keysToDelete = <String>[];
    for (var key in _chaptersBox!.keys) {
      if (key.toString().startsWith('${bookCode}_')) {
        keysToDelete.add(key.toString());
      }
    }
    await _chaptersBox!.deleteAll(keysToDelete);
  }

  static Future<void> replaceChaptersForBook(
    String bookCode,
    List<Chapter> newChapters,
  ) async {
    _checkInitialization();
    await deleteChaptersByBookCode(bookCode);
    await _saveChapters(newChapters);
  }

  static void clearAll() {
    _checkInitialization();
    _booksBox!.clear();
    _chaptersBox!.clear();
  }

  static void _checkInitialization() {
    if (_booksBox == null || _chaptersBox == null) {
      throw Exception('HiveStorage not initialized. Call init() first.');
    }
  }

  static void close() {
    if (_booksBox != null) {
      _booksBox!.close();
    }
    if (_chaptersBox != null) {
      _chaptersBox!.close();
    }
  }
}
